//
//  JLLogger.swift
//  JLLogger
//
//  Created by Jiang Chencheng on 2024/8/14.
//

import Foundation
import OSLog

public final class JLLogger {}

public extension JLLogger {
    
    static let defaultSubsystem = "logger.djangoc.com"
    static let defaultCategory = "main"
    
    private static func logEarlierVersionAvailable(subsystem: String, category: String, level: String, _ message: String) {
        let currentDate = Date()
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
        let formattedDate = dateFormatter.string(from: currentDate)
        print("[\(level)][\(formattedDate)][\(subsystem)][\(category)]\(message)")
    }
     
    static func trace(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.trace("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "trace", message)
        }
    }
    
    static func debug(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.debug("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "debug", message)
        }
    }
    
    static func info(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.info("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "info", message)
        }
    }
    
    static func notice(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.notice("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "notice", message)
        }
    }
    
    static func warning(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.warning("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "warning", message)
        }
    }
    
    static func error(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.error("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "error", message)
        }
    }
    
    static func critical(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.critical("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "critical", message)
        }
    }
    
    static func fault(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        if #available(iOS 14.0, *) {
            let logger = Logger(subsystem: subsystem, category: category)
            logger.fault("\(message)")
        } else {
            logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "fault", message)
        }
    }
    
    static func stdio(subsystem: String = defaultSubsystem, category: String = defaultCategory, _ message: String) {
        logEarlierVersionAvailable(subsystem: subsystem, category: category, level: "stdio", message)
    }
}
